Passed
Push — master ( 795d23...149f73 )
by Grant
06:52 queued 12s
created

queries.ts ➔ empty   A

Complexity

Conditions 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 5
dl 0
loc 9
c 0
b 0
f 0
rs 10
cc 1
1
/**
2
 * Shortcut function that returns the id attribute of an object.
3
 * @param item
4
 */
5
export function getId<T extends { id: number }>(item: T): number {
6
  return item.id;
7
}
8
9
export function identity<T>(value: T): T {
10
  return value;
11
}
12
13
/**
14
 * Returns true if value is not null or undefined.
15
 * Can be used to filter nulls and undefined values out of an array.
16
 * @param item
17
 */
18
export function notEmpty<T>(value: T | null | undefined): value is T {
19
  return value !== null && value !== undefined;
20
}
21
22
export function stringNotEmpty(value: string | null): value is string {
23
  return notEmpty(value) && value.length > 0;
24
}
25
26
/**
27
 * Returns true if value id null OR undefined.
28
 * @param item
29
 */
30
export function empty<T>(
31
  value: T | null | undefined,
32
): value is null | undefined {
33
  return value === null || value === undefined;
34
}
35
36
/**
37
 * From an array of objects, return the first object with a specific id value.
38
 * @param objs
39
 * @param id
40
 */
41
export function find<T extends { id: number }>(
42
  objs: T[],
43
  id: number,
44
): T | null {
45
  const found = objs.filter((item) => item.id === id);
46
  return found.length > 0 ? found[0] : null;
47
}
48
49
/**
50
 * Return all objects from array with the specified key-value attribute.
51
 * @param objs
52
 * @param prop
53
 * @param value
54
 */
55
export function where<T, K extends keyof T>(
56
  objs: T[],
57
  prop: K,
58
  value: any,
59
): T[] {
60
  return objs.filter((obj) => prop in obj && obj[prop] === value);
61
}
62
63
/**
64
 * Return first object from array with the specified key-value attribute.
65
 * @param objs
66
 * @param prop
67
 * @param value
68
 */
69
export function whereFirst<T, K extends keyof T>(
70
  objs: T[],
71
  prop: K,
72
  value: any,
73
): T {
74
  return where(objs, prop, value)[0];
75
}
76
77
/**
78
 * Map each key-value attribute of an object into an array
79
 * @param object
80
 * @param mapFn
81
 */
82
export function objectMap<A, B>(
83
  object: {
84
    [key: string]: A;
85
  },
86
  mapFn: (key: string, value: A) => B,
87
): B[] {
88
  return Object.keys(object).reduce((result: B[], key: string): B[] => {
89
    result.push(mapFn(key, object[key]));
90
    return result;
91
  }, []);
92
}
93
94
interface IndexedObject<T> {
95
  [key: string]: T;
96
}
97
98
/**
99
 * Maps an array of items into an object, with each transformed into an attribute
100
 * @param items array of objects
101
 * @param keyFn Function that returns a unique key for each object. Typically the getId function.
102
 * @param valFn Function that returns a new value for each object.
103
 */
104
export function mapToObjectTrans<A, B>(
105
  items: A[],
106
  keyFn: (item: A) => string | number,
107
  valFn: (item: A) => B,
108
): IndexedObject<B> {
109
  return items.reduce((result: IndexedObject<B>, item: A): IndexedObject<B> => {
110
    const key = keyFn(item);
111
    result[key] = valFn(item);
112
    return result;
113
  }, {});
114
}
115
116
/**
117
 * Maps an array of items into an object, with each item set as an attribute.
118
 * @param items array of objects
119
 * @param keyFn Function that returns a unique key for each object. Typically the getId function.
120
 */
121
export function mapToObject<T>(
122
  items: T[],
123
  keyFn: (item: T) => string | number,
124
): IndexedObject<T> {
125
  return mapToObjectTrans(items, keyFn, (item): T => item);
126
}
127
128
/**
129
 * Checks if an object has an attribute with a particular key
130
 * @param object
131
 * @param key
132
 */
133
export function hasKey<T>(
134
  object: { [key: string]: T },
135
  key: string | number,
136
): boolean {
137
  return object[key] !== undefined;
138
}
139
140
/**
141
 * Returns the value at the specified key. If the key is not present, throws an error.
142
 * @param object
143
 * @param key
144
 * @param errorMessage
145
 */
146
export function getOrThrowError<T>(
147
  object: { [key: string]: T },
148
  key: string | number,
149
  errorMessage: string,
150
): T {
151
  if (!hasKey(object, key)) {
152
    throw new Error(errorMessage);
153
  }
154
  return object[key];
155
}
156
157
/** Return a copy of the object with specific property removed */
158
export function deleteProperty<T, K extends keyof T>(
159
  obj: T,
160
  key: K,
161
): Omit<T, K> {
162
  const { [key]: _, ...newObj } = obj;
163
  return newObj;
164
}
165
166
/**
167
 * Iterate through the properties of the object, checking which return true for the filterFunction.
168
 * Return a copy of the object, without the properties that don't pass the filter.
169
 */
170
export function filterObjectProps<T>(
171
  obj: IndexedObject<T>,
172
  filter: (value: T) => boolean,
173
): IndexedObject<T> {
174
  return Object.entries(obj).reduce(
175
    (newObj: IndexedObject<T>, [key, value]): IndexedObject<T> => {
176
      if (filter(value)) {
177
        newObj[key] = value;
178
      }
179
      return newObj;
180
    },
181
    {},
182
  );
183
}
184
185
/** Return a copy of the list with duplicate elements removed */
186
export function uniq<T>(x: T[]): T[] {
187
  return Array.from(new Set(x));
188
}
189